<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>


<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />

<meta name="theme-color" content="#f8f5ec" />
<meta name="msapplication-navbutton-color" content="#f8f5ec">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="#f8f5ec">



  <meta name="description" content="如何接入易班第三方登录"/>




  <meta name="keywords" content="第三方登录, 八一" />



  <meta name="baidu-site-verification" content="HhUstaSjr0" />



  <meta name="google-site-verification" content="UA-102975942-1" />






  <link rel="alternate" href="/atom.xml" title="八一">




  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=2.6.0" />



<link rel="canonical" href="https://bay1.top/2018/04/04/如何接入易班第三方登录/"/>


<link rel="stylesheet" type="text/css" href="/css/style.css?v=2.6.0" />
<link rel="stylesheet" type="text/css" href="/css/prettify.css" media="screen" />
<link rel="stylesheet" type="text/css" href="/css/sons-of-obsidian.css" media="screen" />



  <link rel="stylesheet" type="text/css" href="/lib/fancybox/jquery.fancybox.css" />




  
  <script id="baidu_analytics">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?9a885cc9fb6cd7bcef579deb8efe8a70";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>



  <script id="google_analytics">
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
        })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

        ga('create', 'UA-102975942-1', 'auto');
        ga('send', 'pageview');
  </script>










    <title> 如何接入易班第三方登录 - 八一 </title>
  </head>

  <body><div id="mobile-navbar" class="mobile-navbar">
  <div class="mobile-header-logo">
    <a href="/." class="logo">八一</a>
  </div>
  <div class="mobile-navbar-icon">
    <span></span>
    <span></span>
    <span></span>
  </div>
</div>

<nav id="mobile-menu" class="mobile-menu slideout-menu">
  <ul class="mobile-menu-list">
    
      <a href="/archives">
        <li class="mobile-menu-item">
          
          
            文章
          
        </li>
      </a>
    
      <a href="/tags">
        <li class="mobile-menu-item">
          
          
            标签
          
        </li>
      </a>
    
      <a href="/about">
        <li class="mobile-menu-item">
          
          
            关于/友链
          
        </li>
      </a>
    
      <a href="/search">
        <li class="mobile-menu-item">
          
          
            站内搜索
          
        </li>
      </a>
    
  </ul>
</nav>

    <div class="container" id="mobile-panel">
      <header id="header" class="header"><div class="logo-wrapper">
  <a href="/." class="logo">八一</a>
</div>

<nav class="site-navbar">
  
    <ul id="menu" class="menu">
      
        <li class="menu-item">
          <a class="menu-item-link" href="/archives">
            
            
              文章
            
          </a>
        </li>
      
        <li class="menu-item">
          <a class="menu-item-link" href="/tags">
            
            
              标签
            
          </a>
        </li>
      
        <li class="menu-item">
          <a class="menu-item-link" href="/about">
            
            
              关于/友链
            
          </a>
        </li>
      
        <li class="menu-item">
          <a class="menu-item-link" href="/search">
            
            
              站内搜索
            
          </a>
        </li>
      
    </ul>
  
</nav>

      </header>

      <main id="main" class="main">
        <div class="content-wrapper">
          <div id="content" class="content">
            
  
  <article class="post">
    <header class="post-header">
      <h1 class="post-title">
        
          如何接入易班第三方登录
        
      </h1>

      <div class="post-meta">
        <span class="post-time">
          2018-04-04
        </span>
        
        
        
      </div>
    </header>

    
    
  <div class="post-toc" id="post-toc">
    <h2 class="post-toc-title">文章目录</h2>
    <div class="post-toc-content">
      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#获取授权令牌"><span class="toc-text">获取授权令牌</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#获取授权凭证"><span class="toc-text">获取授权凭证</span></a></li></ol>
    </div>
  </div>


    <div class="post-content">
      
        <p>工作室接手易班,免不了的要在他的平台上做些事情,第一次去实现第三方登录应用<br>记录下(实际为了填博客)<a id="more"></a></p>
<blockquote>
<p>首先一句话总结方法吧:看文档………<br>感觉每个第三方调用使用都是差不多的</p>
</blockquote>
<p><img src="https://s1.ax1x.com/2018/04/04/C93q8P.png" alt="易班"></p>
<p>这是官方给出的易班授权的流程图<br>看来我之后我们应该能很明白我们要做两件事情:</p>
<ol>
<li>获取授权令牌</li>
<li>通过授权令牌获取授权凭证</li>
</ol>
<blockquote>
<p>当得到授权凭证,我们就能通过授权凭证改进<br>我们原本鉴权以适应第三方登录<br><a href="https://open.yiban.cn/wiki/index.php?page=%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E" target="_blank" rel="noopener">官方原理</a>就不重复了,只是展示一下实践过程的代码</p>
</blockquote>
<h2 id="获取授权令牌"><a href="#获取授权令牌" class="headerlink" title="获取授权令牌"></a>获取授权令牌</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Getcode_baseurl = <span class="string">'https://oauth.yiban.cn/code/html?client_id='</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 重定向登录页面</span></span><br><span class="line"><span class="meta">@oauth.route('/login', methods=['GET'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">redirect_codeurl</span><span class="params">()</span>:</span></span><br><span class="line">    getcode_url = Getcode_baseurl + current_app.config[<span class="string">'APPID'</span>]+<span class="string">'&amp;redirect_uri='</span> + \</span><br><span class="line">        current_app.config[<span class="string">'REDIRECT_URI'</span>] + \</span><br><span class="line">        <span class="string">'&amp;state='</span>+current_app.config[<span class="string">'STATE'</span>]</span><br><span class="line">    <span class="keyword">return</span> redirect(getcode_url)</span><br></pre></td></tr></table></figure>
<blockquote>
<p>首先我们获取第一步需要的授权令牌<br>由易班文档我们可以设置用户点击易班登录的时候<br>把用户重定向到授权页面,即用户访问/api/yiban/login用flask中redirect<br>重定向到getcode_url<br>用户同意授权后,会被重定向到我们管理后台设置的callback地址<br>并携带授权令牌code,即:</p>
</blockquote>
<figure class="highlight accesslog"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">127.0.0.1</span> - - <span class="string">[04/Apr/2018 17:56:34]</span> <span class="string">"<span class="keyword">GET</span> /api/yiban/callback?code=846b11408419865fea4365f473b103eef4410cda&amp;state=asdnajisdnajfbnjsk HTTP/1.1"</span> <span class="number">200</span> -</span><br></pre></td></tr></table></figure>
<h2 id="获取授权凭证"><a href="#获取授权凭证" class="headerlink" title="获取授权凭证"></a>获取授权凭证</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@oauth.route('/callback', methods=['GET'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">redirect_tokenurl</span><span class="params">()</span>:</span></span><br><span class="line">    code = request.args.get(<span class="string">'code'</span>)</span><br><span class="line">    gettoken_url = Gettoken_baseurl + code + <span class="string">'&amp;client_id='</span> + \</span><br><span class="line">        current_app.config[<span class="string">'APPID'</span>] + <span class="string">'&amp;client_secret='</span> + current_app.config[<span class="string">'APPSECRET'</span>] + \</span><br><span class="line">        <span class="string">'&amp;redirect_uri='</span>+current_app.config[<span class="string">'REDIRECT_URI'</span>]</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        result_json = requests.get(gettoken_url).json()</span><br><span class="line">    <span class="keyword">except</span> expression <span class="keyword">as</span> identifier:</span><br><span class="line">        <span class="keyword">return</span> jsonify(&#123;<span class="string">'code'</span>: <span class="number">500</span>, <span class="string">'msg'</span>: <span class="string">"服务端发生错误"</span>&#125;)</span><br><span class="line">    <span class="keyword">if</span> <span class="string">'code'</span> <span class="keyword">in</span> result_json.keys():</span><br><span class="line">        <span class="keyword">return</span> jsonify(result_json)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        payload = &#123;</span><br><span class="line">            <span class="string">'client_id'</span>: current_app.config[<span class="string">'APPID'</span>],</span><br><span class="line">            <span class="string">'access_token'</span>: result_json[<span class="string">'access_token'</span>]</span><br><span class="line">        &#125;</span><br><span class="line">        check_token = requests.post(</span><br><span class="line">            <span class="string">'https://openapi.yiban.cn/oauth/token_info'</span>, payload).json()</span><br><span class="line">        <span class="keyword">if</span> check_token[<span class="string">'status'</span>] == <span class="number">404</span>:</span><br><span class="line">            <span class="keyword">return</span> jsonify(&#123;<span class="string">'code'</span>: <span class="number">404</span>, <span class="string">'msg'</span>: <span class="string">"令牌已过期"</span>&#125;)</span><br><span class="line">        check_admin = Admin.query.filter_by(</span><br><span class="line">            id=result_json[<span class="string">'userid'</span>]).first()</span><br><span class="line">        <span class="keyword">if</span> check_admin:</span><br><span class="line">        	check_admin.access_token = result_json[<span class="string">'access_token'</span>]</span><br><span class="line">        	db.session.add(check_admin)</span><br><span class="line">            token = check_admin.generate_auth_token()</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            admin = Admin(id=result_json[<span class="string">'userid'</span>],</span><br><span class="line">                          access_token=result_json[<span class="string">'access_token'</span>],</span><br><span class="line">                          expires=result_json[<span class="string">'expires'</span>])</span><br><span class="line">            db.session.add(admin)</span><br><span class="line">            token = admin.generate_auth_token()</span><br><span class="line">        db.session.commit()</span><br><span class="line">    <span class="keyword">return</span> jsonify(&#123;<span class="string">'code'</span>: <span class="number">200</span>, <span class="string">'msg'</span>: <span class="string">"登录成功"</span>, <span class="string">'token'</span>: token.decode(<span class="string">'ascii'</span>)&#125;)</span><br></pre></td></tr></table></figure>
<blockquote>
<p>接下里我们要做的也很明显,就是通过上一步得到的授权令牌来进一步获取授权凭证<br>首先用户同意授权会被重定向到/api/yiban/callback<br>我们通过获取url中的code进一步request获取凭证的链接就可以完成<br>然后我们怎么和原本的用户鉴权结合呢？？</p>
</blockquote>
<p>首先每个项目你所用的鉴权方式可能不一样<br>这里我使用了第三方库flask_httpauth</p>
<blockquote>
<p>这个方式的鉴权是获取填写的用户名和密码或者是你POST<br>过来的token,然后通过验证用户名和密码或者解密token来实现鉴权<br>也就是如果我们使用第三方登录,只需要保存或者更新token到对应的第三方用户表段就行了<br>再进行其他路由访问的时候携带token就行了<br>(当然你要拓展用户表表段以适应第三方登陆的保存)</p>
</blockquote>
<p><img src="https://s1.ax1x.com/2018/04/04/C9YF2t.png" alt="yiban"><br><img src="https://s1.ax1x.com/2018/04/04/C9J759.png" alt="yiban"></p>

      
    </div>

    
      
      



      
      
    

    
      <footer class="post-footer">
        
          <div class="post-tags">
            
              <a href="/tags/第三方登录/">第三方登录</a>
            
          </div>
        
        
        
  <nav class="post-nav">
    
      <a class="prev" href="/2018/05/11/模拟上传multipart-form-data-脚本生成时间轴/">
        <i class="iconfont icon-left"></i>
        <span class="prev-text nav-default">模拟上传multipart/form-data/脚本生成时间轴</span>
        <span class="prev-text nav-mobile">上一篇</span>
      </a>
    
    
      <a class="next" href="/2018/03/13/Docker中SQlite的配置和挂载/">
        <span class="next-text nav-default">Docker中SQlite的配置和挂载</span>
        <span class="prev-text nav-mobile">下一篇</span>
        <i class="iconfont icon-right"></i>
      </a>
    
  </nav>

      </footer>
    

  </article>


          </div>
          
  <div class="comments" id="comments">
      <div id="disqus_thread">
        <noscript>
          Please enable JavaScript to view the
          <a href="//disqus.com/?ref_noscript">comments powered by Disqus.</a>
        </noscript>
      </div> 
    </div>
  </div>


        </div>
      </main>

      <footer id="footer" class="footer">

  <div class="social-links">
    
      
        
          <a href="https://github.com/bay1" class="iconfont icon-github" title="github"></a>
        
      
    
      
        
          <a href="http://weibo.com/3190704711/profile?topnav=1&wvr=6&is_all=1" class="iconfont icon-weibo" title="weibo"></a>
        
      
    
      
    
      
    
      
    
    
    
  </div>


<div class="copyright">
  <span class="copyright-year">
    
    &copy; 
     
      2016 - 
    
    2018
    <span class="author">bay1</span>
  </span>
</div>
      </footer>

      <div class="back-to-top" id="back-to-top">
        <i class="iconfont icon-up"></i>
      </div>
    </div>

    
  
  <script type="text/javascript">
    var disqus_config = function () {
        this.page.url = 'https://bay1.top/2018/04/04/如何接入易班第三方登录/';
        this.page.identifier = '2018/04/04/如何接入易班第三方登录/';
        this.page.title = '如何接入易班第三方登录';
    };
    (function() {
    var d = document, s = d.createElement('script');

    s.src = '//https-blog-flywinky-top-1.disqus.com/embed.js';

    s.setAttribute('data-timestamp', +new Date());
    (d.head || d.body).appendChild(s);
    })();  
  </script>



    
  





  
    <script type="text/javascript" src="/lib/jquery/jquery-3.1.1.min.js"></script>
  

  
    <script type="text/javascript" src="/lib/slideout/slideout.js"></script>
  

  
    <script type="text/javascript" src="/lib/fancybox/jquery.fancybox.pack.js"></script>
  


    <script type="text/javascript" src="/js/src/even.js?v=2.6.0"></script>
<script type="text/javascript" src="/js/src/bootstrap.js?v=2.6.0"></script>
<script src="/js/prettify.js"></script>
<script type="text/javascript">
$(document).ready(function(){
 $('pre').addClass('prettyprint');
   prettyPrint();
 })
</script>
  </body>
</html>
